'''
Created on 20/04/2013

@author: jean
'''
from pm.models.Proyectos import Proyectos
from pm.models.Fases import Fases
from pm.models.Usuarios import Usuarios
from pm.models.UsuariosRolesFases import UsuariosRolesFases
from pm.models.UsuariosRoles import UsuariosRoles
from pm.models.MiembrosComite import MiembrosComite
from pm.models.RolesPermisos import RolesPermisos
from pm.models.Permisos import Permisos
from flask import Flask, session, redirect, url_for, escape, request,Response
from . import ensureParams
from pm.database import db
from sqlalchemy.orm.exc import NoResultFound
import datetime
from pm import app
from . import jsonifiedview
from .LoginViews import islogged
from pm.models.Roles import getRolesByUserName

@app.route('/proyectos/listar', methods=['GET', 'POST']) 
@jsonifiedview
def listarProyectos():
    '''
    Lista los Proyectos existentes en el sistema
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    
    band= False
    
   
    resp = getRolesByUserName(params['id'])
    for r in resp:
        if r==1:
            band= True
    if band== True:
        
        proyectos = Proyectos.query
        proyectos = proyectos.filter(Proyectos.descripcion.like('%' + params['descripcion'] + '%')) if 'descripcion' in params else proyectos
        proyectos = proyectos.filter(Proyectos.estado.like('%' + params['estado'] + '%')) if 'estado' in params else proyectos 
        proyectos = proyectos.filter(Proyectos.cantidad_fases.like('%' + params['cantidad_fases'] + '%')) if 'cantidad_fases' in params else proyectos 
        proyectos = proyectos.filter(Proyectos.nombre.like('%' + params['nombre'] + '%')) if 'nombre' in params else proyectos 
        proyectos = proyectos.filter(Proyectos.fecha_inicio.like('%' + params['fecha_inicio'] + '%')) if 'fecha_inicio' in params else proyectos
        proyectos = proyectos.filter(Proyectos.fecha_fin.like('%' + params['fecha_fin'] + '%')) if 'fecha_fin' in params else proyectos       
        return proyectos.order_by(Proyectos.id_proyecto).all()
    else:
        resp =[]
        usuario = Usuarios.query.filter(Usuarios.user_name == params['id']).one()
        usuariosRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario == usuario.id_usuario).all()
        for ur in usuariosRoles:
            usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_usuario_rol == ur.id_usuario_rol).all()
            for urf in usuariosRolesFases: 
                proyectos = Proyectos.query.filter(Proyectos.id_proyecto == urf.id_proyecto)
                proyectos = proyectos.filter(Proyectos.descripcion.like('%' + params['descripcion'] + '%')) if 'descripcion' in params else proyectos
                proyectos = proyectos.filter(Proyectos.estado.like('%' + params['estado'] + '%')) if 'estado' in params else proyectos 
                proyectos = proyectos.filter(Proyectos.cantidad_fases.like('%' + params['cantidad_fases'] + '%')) if 'cantidad_fases' in params else proyectos 
                proyectos = proyectos.filter(Proyectos.nombre.like('%' + params['nombre'] + '%')) if 'nombre' in params else proyectos 
                proyectos = proyectos.filter(Proyectos.fecha_inicio.like('%' + params['fecha_inicio'] + '%')) if 'fecha_inicio' in params else proyectos
                proyectos = proyectos.filter(Proyectos.fecha_fin.like('%' + params['fecha_fin'] + '%')) if 'fecha_fin' in params else proyectos       
                proyectos = proyectos.all()
                if proyectos:
                    for p in proyectos:
                        if p not in resp:
                            resp.append(p)
                    
        return resp

@app.route('/proyectos/crear', methods=['GET', 'POST']) 
@jsonifiedview
def crearProyecto():
    '''
        Crea un nuevo Proyecto

    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
  
    
    if not ensureParams(params,['descripcion', 'cantidad_fases', 'nombre', 'fecha_inicio','fecha_fin', 'user_name'] ): 
        response ={"success" : False , "msg" : "Parametros Insuficientes"} 
        return response   
      
    
    if params['cantidad_fases']<1:
        response ={"success" : False , "msg" : "La cantidad de Fases debe ser mayor o igual a 1"} 
        return response
    try:
        now = datetime.datetime.now()
        proyecto = Proyectos(params['descripcion'],1,params['cantidad_fases'],params['nombre'],params['fecha_inicio'],params['fecha_fin'],now , 0, False,True)
        db.session.add(proyecto)
        db.session.commit()
        usuario = Usuarios.query.filter(Usuarios.user_name == params['user_name']).one()
        usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario == usuario.id_usuario).filter(UsuariosRoles.id_rol == 2).one()
        #Se asigna el lider al proyecto
        usuarioRolesFases = UsuariosRolesFases(usuariosRoles.id_usuario_rol, None,proyecto.id_proyecto,True,None)
        db.session.add(usuarioRolesFases)
        db.session.commit()
        #Se crea el comite del proyecto
        miembrosComite= MiembrosComite(usuario.id_usuario,proyecto.id_proyecto)
        db.session.add(miembrosComite)
        db.session.commit()
        response ={"success" : True , "msg" : "Creacion Exitosa"}
        return response
    except Exception, e:
        db.session.rollback()
        response ={"success" : False , "msg" : e}
        return response 
    
@app.route('/proyectos/cambiarestado', methods=['GET', 'POST']) 
@jsonifiedview
def iniciarProyecto():
    '''
        Cambia el estado de un proyecto

    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
  
    
    try:
        proyecto = Proyectos.query.filter(Proyectos.id_proyecto == params['id']).one()
        
    except NoResultFound:
        response ={"success" : False , "msg" : "Proyecto no encontrado"} 
        return response
    
    if proyecto.activo == False:
        response ={"success" : False , "msg" : "El proyecto se encuentra en estado inactivo"} 
        return response
    
    if proyecto.estado!=1:
        response ={"success" : False , "msg" : "El proyecto no se encuentra en estado no iniciado"}
        return response
    
    contador= Fases.query.filter(Fases.id_proyecto==params['id']).count()
    if proyecto.cantidad_fases != contador:
        response = {"success":False,"msg": "Aun faltan Fases a ser definidas"}
        return response
    try:
        proyecto.query.filter(Proyectos.id_proyecto == params['id']).update({'estado':2})
        db.session.commit()
        response ={"success" : True , "msg" : "Inicializacion Exitosa"}
        return response
    except Exception, e:
        db.session.rollback()
        response ={"success" : False , "msg" : "Error en la base de datos"}
        return response 

@app.route('/proyectos/modificar', methods=['GET', 'POST']) 
@jsonifiedview
def modificarProyecto():
    '''
        Modifica la descripcion o el nombre del proyecto. En caso de que el proyecto esta
        en estado no iniciado, se podra modificar el numero de fases
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    
        
    #Buscamos el proyecto
    proyecto = Proyectos.query.filter(Proyectos.id_proyecto == params['id_proyecto']).one()
    
    contadorFasesActivas= Fases.query.filter(Fases.id_proyecto==params['id_proyecto']).filter(Fases.activo==True).count()

    cant = int(str(params ['cantidad_fases']))
    
    if contadorFasesActivas > cant:
        response ={"success" : False , "msg" : "La cantidad de Fases ingresada es menor a la cantidad de fases ya definidas!!"}
        return response 
    
    if proyecto.cantidad_fases != cant:
        if proyecto.estado != 1:
            response ={"success" : False , "msg" : "El proyecto que trata de modificar se encuentra en Estado Iniciado!!"}
            return response
    try:    
        proy =Proyectos.query.filter(Proyectos.id_proyecto == params['id_proyecto']).update({'descripcion': params['descripcion'],'nombre': params['nombre'], 'cantidad_fases': params['cantidad_fases']})
        db.session.commit()
        response ={"success" : True , "msg" : "Proyecto modificado exitosamente"}
        return response
    
    except Exception, e:
        response ={"success" : False , "msg" : "Error en la base de datos"}
        return response

    
@app.route('/proyectos/activardesactivar', methods=['GET', 'POST']) 
@jsonifiedview
def activarDesactivar():
    '''
        Activa o desactiva un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    #Comprobamos si el usuario se encuentra logueado
    
    
    try:    
        proy =Proyectos.query.filter(Proyectos.id_proyecto == params['id_proyecto']).update({'activo': params['activo']})
        db.session.commit()
        response ={"success" : True , "msg" : "Proyecto modificado exitosamente"}
        return response
    
    except Exception, e:
        response ={"success" : False , "msg" : "Error en la base de datos"}
        return response
   
@app.route('/proyectos/listarusuariosbyproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def listarUsuariosByProyecto():
    '''
        Listar usuarios que tiene un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
  
    resp = []
    #Comprobamos si el usuario se encuentra Logueado
    
    if not ensureParams(params,['id']): 
        return resp  
    
    usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto ==params['id'])
    for urf in usuariosRolesFases:
        usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol ==urf.id_usuario_rol)
        for ur in usuariosRoles:
            usuarios = Usuarios.query.filter(Usuarios.id_usuario ==ur.id_usuario)
            for u in usuarios:
                if u not in resp:
                    resp.append(u)
                    
    return resp

@app.route('/proyectos/listarusuariosdistinct', methods=['GET', 'POST']) 
@jsonifiedview
def listarUsuariosDistinctPorProyecto():
    '''
        Lista los usuarios que no pertenecen a ese proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
  
    resp = []     
    #Comprobamos si el usuario se encuentra Logueado
    
    usuarios = Usuarios.query.all()
    list= []
    resp = usuarios
    for u in usuarios:
        usuariosRoles = UsuariosRoles.query.filter(UsuariosRoles.id_usuario== u.id_usuario).all()
        for ur in usuariosRoles:
            usuariosRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_usuario_rol == ur.id_usuario_rol).all()
            for urf in usuariosRolesFases:
                if urf.id_proyecto == int(str(params['id_proyecto'])):
                    list.append(u)
                
    for l in list:
        if l in resp:
            resp.remove(l)                
    return resp
        
@app.route('/proyectos/abrir', methods=['GET', 'POST']) 
@jsonifiedview
def abrirProyecto():
    '''
        Lista los usuarios que no pertenecen a ese proyecto
        @param id_proyecto= el id del proyecto que se desea abrir
        @param id_usuario= el id del usuario que desea abrir el proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    resp = []
    respuesta= {}
    
    if not ensureParams(params,['id_proyecto','id_usuario']): 
        respuesta = {"success" : False , 'msg': 'Parametros Insuficientes'}
        return respuesta
    
    #Vemos todos los roles que tiene asignado en ese proyecto
    usuariosRolesFases = UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto == params['id_proyecto']).filter(UsuariosRolesFases.activo == True).all()
    for urf in usuariosRolesFases:
        usuarioRol = UsuariosRoles.query.filter(UsuariosRoles.id_usuario_rol == urf.id_usuario_rol).one()
        if usuarioRol.id_usuario == int(str(params['id_usuario'])):
            rolesPermisos = RolesPermisos.query.filter(RolesPermisos.id_rol == usuarioRol.id_rol).filter(RolesPermisos.activo == True).all()
            for rp in rolesPermisos: 
                permisos = Permisos.query.filter(Permisos.id_permiso == rp.id_permiso).one()
                if permisos.nombre not in resp:
                    resp.append(permisos.nombre)
            
    respuesta = {"success" : True , 'permisosProyecto':resp}
    return respuesta
    
@app.route('/proyectos/activardesactivarrolxproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def activarDesactivarRolxProyecto():
    '''
        Activa o desactiva un rol asociado a un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    #Comprobamos si el usuario se encuentra logueado
    
    
    try:
        id_proyecto=int(str(params['id_proyecto']))
        id_usuario= int(str(params['id_usuario']))
        id_rol= int(str(params['id_rol']))
        activo= params['activo']
        
        miembroComite = MiembrosComite.query.filter(MiembrosComite.id_proyecto == params['id_proyecto']).filter(MiembrosComite.id_usuario == params['id_usuario']).first()
        if miembroComite!= None:
            response ={"success" : False , "msg" : "No se puede desactivar el usuario porque el usuario es miembro del comite"}
            return response
        
        usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.id_rol==id_rol).one()
        usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto== id_proyecto).filter(UsuariosRolesFases.id_usuario_rol==usuarioRoles.id_usuario_rol).update({'activo':activo})
        db.session.commit()
        response ={"success" : True , "msg" : "Modificacion exitosa!!"}
        return response
    except Exception, e:
        response ={"success" : False , "msg" : "Ups!! Hubo un error al intentar desactivar al usuario!!"}
        return response   

@app.route('/proyectos/estadorelacionrolxproyecto', methods=['GET', 'POST']) 
@jsonifiedview
def estadoRelacionRolxProyecto():
    '''
        Ver el campo activo un rol asociado a un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    #Comprobamos si el usuario se encuentra logueado
    
    
    try:
        id_proyecto=int(str(params['id_proyecto']))
        id_usuario= int(str(params['id_usuario']))
        id_rol= int(str(params['id_rol']))
      
        
        usuarioRoles= UsuariosRoles.query.filter(UsuariosRoles.id_usuario==id_usuario).filter(UsuariosRoles.id_rol==id_rol).one()
        usuarioRolesFases= UsuariosRolesFases.query.filter(UsuariosRolesFases.id_proyecto== id_proyecto).filter(UsuariosRolesFases.id_usuario_rol==usuarioRoles.id_usuario_rol).one()
        
        response ={"success" : True ,"activo":usuarioRolesFases.activo}
        return response
    except Exception, e:
        response ={"success" : False , "msg" : "Ups!! Hubo un error al intentar desactivar al usuario!!"}
        return response   
    

@app.route('/proyectos/finalizar', methods=['GET', 'POST']) 
@jsonifiedview
def finalizarProyecto():
    '''
        Ver el campo activo un rol asociado a un proyecto
    '''
    params = {'GET':request.args, 'POST':request.form}[request.method]
    response ={}
    #Comprobamos si el usuario se encuentra logueado
    
    
    try:
        id_proyecto=int(str(params['id_proyecto'])) 
        fases= Fases.query.filter(Fases.id_proyecto==id_proyecto).all()
        estanCerradas=None
        contadorF = 0
        for f in fases:   
            if f.estado!= 3:
                estanCerradas=False 
            if f.estado==3:
                contadorF = contadorF + 1
        proyectoAux= Proyectos.query.filter(Proyectos.id_proyecto==id_proyecto).one()
        if proyectoAux.estado==3:
            response ={"success" : False , "msg" : "El proyecto ya se encuentra cerrado"}
            return response
        
        if contadorF==proyectoAux.cantidad_fases:
            proyecto= Proyectos.query.filter(Proyectos.id_proyecto==id_proyecto).update({'estado':3})
            db.session.commit()
            response ={"success" : True , "msg" : "El proyecto se ha cerrado"}
            return response
        else:
            response ={"success" : False , "msg" : "Ups!! El proyecto aun no puede cerrarse"}
            return response
    except Exception, e:
        response ={"success" : False , "msg" : "Ups!! El proyecto aun no puede cerrarse"}
        return response
     